home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
SourceCode
/
DeveloperLabs
/
Lab3
/
Controller.m
< prev
next >
Wrap
Text File
|
1992-12-19
|
8KB
|
247 lines
/* Controller.m --- Main controller object for the TextLab program.
** Authors: Bruce Blumberg and Ali Ozer, NeXT Developer Support Group
*/
// Controller object is the central object in TextLab. It manages the
// windows, open/save panels, and menu commands.
#import "Controller.h"
#import "TextView.h"
#import <appkit/Application.h>
#import <objc/typedstream.h>
@implementation Controller
// We subclass the Controller "new" so that we can set the application's
// delegate to point to the Controller object. This way open file
// requests from the Workspace get routed to the Controller's
// appOpenFile:type: and appAcceptsAnotherFile methods.
+ new
{
self = [super new];
[NXApp setDelegate:self];
// create instances of support objects
openReq = [OpenPanel new];
saveReq = [SavePanel new];
return self;
}
- showError: (char *)errorMessage
{
NXRunAlertPanel (NULL, errorMessage,"OK",NULL,NULL);
}
// newTextView: is invoked in response to a new empty window request. It
// creates a new window containing a TextView. Note that we want new windows
// to be offset from each other by some amount; hence the use of wRect.
#define ORIGX 100.0
#define ORIGY 100.0
static NXRect wRect = {{ORIGX, ORIGY},{500.0,400.0}};
- newTextView:sender
{
id newTextView;
NXOffsetRect(&wRect, 20.0, -20.0);
if (wRect.origin.y < 0) {wRect.origin.y = ORIGY; wRect.origin.x = ORIGX;}
newTextView = [TextView newFrame:&wRect];
[[newTextView window] setDelegate:self];
return self;
}
// appAcceptsAnotherFile is an application delegate method which
// returns whether it is OK for the application to try to open more files
// with the appOpenFile:type: method. TextLab can indeed open multiple
// windows, so we return YES.
-(BOOL) appAcceptsAnotherFile:sender
{
return (YES);
}
// appOpenFile:type: is called to open the specified file. It is normally
// called by the Application object in response to open requests from the
// Workspace. Here we also route the open requests from the OpenPanel
// to this method (see openRequest:).
-(int) appOpenFile:(char *)fileName type:(char *)fileType
{
return [self openFile:fileName];
}
// openRequest: opens a new file. It puts up a open panel, and, if the user
// doesn't cancel, it reads the specified archive file. If the selected file
// is not a proper archive file, then openRequest: will complain.
- openRequest:sender
{
const char *fileName;
const char *const types[2] = {"tl", NULL};
int ok;
if ([openReq runModalForTypes:types] && (fileName =[openReq filename])) {
[self openFile:fileName];
}
else
[self showError:"Not a valid textlab file."];
return self;
}
-(int) openFile:(const char *)fileName
{
id win;
NXTypedStream *typedStream;
if(!(typedStream = NXOpenTypedStreamForFile(fileName,NX_READONLY))){
[self showError:"error on opening file"];
return NO;
}
else {
win = NXReadObject(typedStream);
NXCloseTypedStream(typedStream);
[win setTitle:fileName];
[[win display] makeKeyAndOrderFront:self];
return YES;
}
}
// saveRequest: saves the current window under its default name (found in
// the title bar). Note that if the title bar is empty or the default title
// is "Untitled" then saveRequest: will put up a save panel, giving the user
// a chance to specify a real title.
- saveRequest:sender
{
const char *fileName;
id curWin = [NXApp mainWindow];
if (curWin == nil)
[self showError:"No active window to save."];
else {
// Check to see if the current window is titled and the title is not
// "Untitled". If so, save the file, else put up a save panel...
fileName = [curWin title];
if (strcmp (fileName, "Untitled"))
[self saveWindow:curWin inPath:fileName];
else [self saveInRequest:sender];
}
return self;
}
// saveInRequest: gives the user a chance to save the current window
// under a new name.
- saveInRequest:sender
{
const char *fileName;
id curWin;
/* EXERCISE #4a *
* Add code to respond to an saveInRequest *
* Hint: Use a SavePanel to get the file name and *
* directory where the document should be saved. *
* You will note that the saveReq instance variable *
* was initialized in the +new method of Controller *
* to point to a SavePanel. SavePanels will automatically *
* append an extension on the file name specified by the *
* the user if you have previously sent it the *
* setRequiredFileType: message passing it the appropriate *
* extension. Once you have done this, you should send it a*
* a method called runModalForDirectory:file: which *
* makes theSavePanel visible and which make it *
* a modal window. Once that method returns you can *
* query the SavePanel for the file name *
* selected (look in the spec sheets for SavePanel). *
* Assuming you used setRequiredFileType: earlier the file *
* name returned will have the appropriate extension *
* Finally you should call the saveWindow:inPath: *
* method of Controller which will actually save the *
* document. Note the first argument to saveWindow is *
* the id of the window containing the document to be *
* saved. Look at the specSheets for the Application *
* object to see what method to use to get the id of the *
* current main window. In fact you will probably want to *
* get the id of the main window first thing in here so *
* you can use its title as the default file name for *
* the file in which the window will be stored */
return self;
}
// saveWindow writes a window out the archive file whose name is specified
// by the second argument. The title of the current window is also set
// accordingly.
- saveWindow:(id)win inPath:(const char *)name
{
NXTypedStream *typedStream;
[win setTitle:name];
/* EXERCISE #4b *
* Add code to store win and its contents *
* in an file called name.Hint: you will want to *
* use typedStreams to write out the window and its *
* contents. The code to do this will look similar to the *
* code in openFile: so be sure to look at that code. You *
* will need to do 3 things. 1) Open a typedStream on a *
* file named name using NXOpenTypedStreamForFile() *
* 2) Write out the window to the typedStream using *
* NXWriteRootObject(). 3) Close the typedStream. */
return self;
}
// Printing is rather simple; just send printPSCode: to the text view
// you wish to print. The print panel will automatically pop up and unless
// the user cancels the printout the text view will be printed.
- printRequest:sender
{
/* EXERCISE 5 *
* Add code to assign curText to point to *
* view which should be printed. Hint: it is the *
* docView of the TextView in the application's *
* mainWindow. Look at the spec sheets for the *
* Application class to see how to get the id of *
* the current main window */
id curText = nil;
if (curText == nil) [self showError:"No active window to print."];
else {
/* EXERCISE 5b *
* Add code to print view *
* *
* */
}
return self;
}
// closeRequest closes the current window by simulating a click on the
// closebutton. A check should probably be added to give the user the
// option of saving the window before closing
- closeRequest:sender
{
[[NXApp mainWindow] performClose:sender];
return self;
}
// This method will get called before a window is closed and
// will give the user an opportunity to save their file. It then returns
// self indicating that the window may be closed.
- windowWillClose:(id)whichWin
{
return self;
}
@end